from django.shortcuts import render
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import ListAPIView,RetrieveAPIView,CreateAPIView,UpdateAPIView
from random import randint
from django_redis import get_redis_connection
from meiduo_mall.libs.yuntongxun.sms import CCP
from threading import Thread
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from celery_tasks.sms_code.tasks import send_sms_code
from users.models import User
from users.serializers import UserSerializers,UserShowSerializers,UserEmailSerializers


# Create your views here.

# def sed_sms_code(mobile,sms_code):
#     ccp = CCP()
#     ccp.send_template_sms(mobile, [sms_code, '5'], 1)


class SMS_Code_View(APIView):
    def get(self,request,mobile):

        #1 获取前端传递手机号

        #2 验证手机号格式

        # 建立redis链接
        conn = get_redis_connection('sms_code')

        # 获取数据内容，链接redis
        flag = conn.get('sms_code_flag_%s' % mobile)

        # 判断前端的请求时间间隔是否在60内
        if flag:
            return Response({'error': '请求太过频繁'}, status=403)


        # 3 生成短信验证码
        sms_code = '%06d' % randint(0, 999999)
        print(sms_code)

        #管道方法，由管道对象进行写入操作
        pl = conn.pipeline()

        # 4 保存到redis缓存,key值手机号,过期时间,写入的value值  链接redis
        pl.setex('sms_code_%s' % mobile, 300, sms_code)

        #写入一个标志数据 超过有效期60秒会失效，链接redis
        pl.setex('sms_code_flag_%s' % mobile, 60, 2)

        # 将指令通过管道传递给redis 可以将写入数据指令放入管道,由管道执行，
        # 返回结果也给管道，执行一次即可
        pl.execute()

        # 5 发送短信验证码
        # ccp = CCP()
        # ccp.send_template_sms(mobile, [sms_code, '5'], 1 )
        # 线程执行发送短信
        # t = Thread(target=sed_sms_code,kwargs={'mobile':mobile,'sms_code':sms_code})
        # t.start()

        #使用celery发送短信 ,调用delay，会通知任务执行者有没有这个任务，并执行
        #执行需要终端启动celery
        # 命令：celery -A celery_tasks.main worker -l info
        send_sms_code.delay(mobile,sms_code)


        # 6 返回结果
        return Response('OK')


# 用户注册

# 判断用户名重复
class UserNameView(APIView):

    def get(self,request,username):
        count = User.objects.filter(username=username).count()

        return Response(
            {'count':count}
        )

# 判断手机号是否重复
class MobileView(APIView):

    def get(self,request,mobile):
        count = User.objects.filter(mobile=mobile).count()

        return Response(
            {'count':count}
        )

# 注册用户
# 涉及到保存使用:CreateAPIView
class UserView(CreateAPIView):
    # 指定序列化器
    serializer_class = UserSerializers


# 展示用户信息
class UserShowView(RetrieveAPIView):
    serializer_class = UserShowSerializers
    queryset = User.objects.all()

    # 重写get_object
    def get_object(self):
        return self.request.user

# 保存更新邮箱
class UserEmailView(UpdateAPIView):
    serializer_class = UserEmailSerializers

    # 重写get_object
    def get_object(self):
        return self.request.user

# 邮箱验证
class UserEmailVifyView(APIView):
    def get(self,request):
        # 1 获取前端数据
        token = request.query_params.get('token')
        # 2 解密token
        tjs = TJS(settings.SECRET_KEY,300)
        try:
            data = tjs.loads(token)
        except:
            return Response({'errors':'错误的token'},status=400)
        # 3 获取解密后的用户数据
        username = data.get('username')
        # 4 根据用户名查询用户对象
        user = User.objects.get(username=username)
        # 5 更新用户的邮箱验证状态
        user.email_active = True
        user.save()
        # 6 返回验证状态
        return  Response({'email_active':user.email_active})




























